package com.jnchen.jwt.impl;

import com.jnchen.jwt.api.JwtInterface;
import com.jnchen.jwt.entity.User;
import com.jnchen.jwt.util.RsaUtil;
import io.fusionauth.jwt.Signer;
import io.fusionauth.jwt.Verifier;
import io.fusionauth.jwt.domain.JWT;
import io.fusionauth.jwt.rsa.RSASigner;
import io.fusionauth.jwt.rsa.RSAVerifier;

import java.io.IOException;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;

/**
 * fusion auth 实现
 *
 * @author jnchen
 * @date 2020/10/30 10:56
 */
public class FusionAuthImpl implements JwtInterface {
    private static final Signer SIGNER;
    private static final Verifier VERIFIER;

    static {
        String[] pemKeys = new String[0];
        try {
            pemKeys = RsaUtil.getPemRsaKey();
        } catch (IOException e) {
            e.printStackTrace();
        }
        SIGNER = RSASigner.newSHA512Signer(
                pemKeys[0]
        );
        VERIFIER = RSAVerifier.newVerifier(
                pemKeys[1]
        );
    }

    @Override
    public String createJwt(User user, long expireIn) {
        JWT jwt = new JWT()
                .addClaim("id", user.getId())
                .addClaim("name", user.getName())
                .addClaim("operations", user.getOperations())
                .setExpiration(ZonedDateTime.ofInstant(new Date(System.currentTimeMillis() + expireIn).toInstant(), ZoneId.systemDefault()));
        return JWT.getEncoder().encode(jwt, SIGNER);
    }


    @Override
    @SuppressWarnings({"unchecked", "rawtypes"})
    public User parseJwt(String token) {
        JWT jwt = JWT.getDecoder().decode(token, VERIFIER);
        User user = new User();
        user.setId(jwt.getInteger("id"));
        user.setName(jwt.getString("name"));
        user.setOperations((List) jwt.getList("operations"));
        return user;
    }

    @Override
    public boolean checkJwt(String token) {
        try {
            JWT jwt = JWT.getDecoder().decode(token, VERIFIER);
            return !jwt.isExpired();
        } catch (Exception e) {
            return false;
        }
    }
}
